package com.itealabs.postjson.ext;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.itealabs.postjson.JsonCall;
import com.itealabs.postjson.JsonCallWaiter;
import com.itealabs.postjson.JsonCallWaiterLocator;
import com.itealabs.postjson.JsonRequest;
import com.itealabs.postjson.JsonRequestWaiter;
import com.itealabs.postjson.JsonResponse;
import com.itealabs.postjson.JsonReturn;
import com.itealabs.postjson.JsonReturn.State;

/**
 * 
 * @version $Id: SimpleJsonRequestWaiter.java 13 2010-04-23 05:50:41Z iteahere $
 * @author itea
 * @date 2010-4-16
 */
public class SimpleJsonRequestWaiter implements JsonRequestWaiter {

	private JsonCallWaiterLocator jsonCallWaiterLocator;
	
	static JsonCallWaiter notFoundCallWaiter = new JsonCallWaiter() {
		public JsonReturn service(JsonCall jsonCall,
				Map<String, Object> ctx) {
			return new JsonReturn(State.ERROR, 
					new NoSuchMethodException("NOT FOUND: "+ jsonCall.getMethod()));
		}
	};
	
	public void service(JsonRequest jsonReq, JsonResponse jsonResp,
			Map<String, Object> ctx) {
		
		List<JsonReturn> rtls = new ArrayList<JsonReturn>(jsonReq.getCalls().size());
		
		for (JsonCall jc : jsonReq.getCalls())
			rtls.add(callAndGetReturn(jc, ctx));
		
		jsonResp.setReturns(rtls);
	}
	
	private JsonReturn callAndGetReturn(JsonCall jc, Map<String, Object> ctx) {
		Long idx = jc.getIdx();
		JsonReturn rt = null;
		try {
			rt = getCallWaiter(jc.getMethod()).service(jc, ctx);
			rt.setIdx(idx);
			return rt;
		} catch (Exception e) {
			//e.printStackTrace(); // FIXME remove
			return new JsonReturn(idx, State.ERROR, e);
		}
	}
	
	protected JsonCallWaiter getCallWaiter(String method) {
		JsonCallWaiter callWaiter = jsonCallWaiterLocator.getCallWaiter(method);
		return callWaiter == null ? notFoundCallWaiter : callWaiter;
	}

	public JsonCallWaiterLocator getJsonCallWaiterLocator() {
		return jsonCallWaiterLocator;
	}

	public void setJsonCallWaiterLocator(JsonCallWaiterLocator jsonCallWaiterLocator) {
		this.jsonCallWaiterLocator = jsonCallWaiterLocator;
	}

}
